#include"kdf.h"
#include"sm3.h"
#include<malloc.h>
#include<stdlib.h>
#include<memory.h>

/**
 * 密钥派生函数。哈希函数采用SM3算法.
 * 
 * \param out 输出的字符串
 * \param out_len 输出的字节数
 * \param input 输入的字符串
 * \param input_len 输入的字节数
 * \return 
 */
void kdf(uint8_t* out, const size_t out_len,const uint8_t* input, size_t input_len){
	// 预处理
	
	// 1.初始化变量
	uint32_t n = out_len / 32;

	size_t temp_len = input_len + 4;
	uint8_t* temp = (uint8_t*)malloc(temp_len * sizeof(uint8_t));
	//uint8_t* temp = input;

	uint8_t block[32];
	
	size_t hash_len = input_len + 4;

	sm3_context ctx;

	memcpy(temp, input, input_len);

	// 2.循环哈希
	// 循环次数 n
	for(uint32_t count = 1;  count <= n; count++)
	{
		// 2.1.拼接 input + count
		PUT_UINT_BE(count, temp, input_len);
		
		// 2.2.对 input + count 进行哈希
		sm3_init(&ctx);

		sm3_update(&ctx, temp, hash_len);

		// 2.3.将哈希的结果放到输出的数组里面
		sm3_finish(out + (count - 1) * 32, &ctx);
	}



	// 3.处理 out_len/32 ! = n 的情况
	if (n * 32 != out_len) {
		// 3.1.处理第n+1次哈希
		// print_chars_by_hex("temp测试", temp, input_len);

		PUT_UINT_BE(n + 1, temp, input_len);

		//print_chars_by_hex("temp测试", temp, input_len + 4);

		sm3_init(&ctx);

		sm3_update(&ctx, temp, hash_len);

		sm3_finish(block, &ctx);

		// 3.2.复制最后几个字节的元素
		memcpy(out + n * 32, block, out_len - n * 32);
	}

	// 4.释放变量
	free(temp);
}
